using System.Collections.Generic;
using System;
using SharpArch.Core;
using GoldenBicycleCompany.Core;
using GoldenBicycleCompany.ApplicationServices.ViewModels;
using GoldenBicycleCompany.Core.QueryDtos;
using GoldenBicycleCompany.Core.RepositoryInterfaces;
 

namespace GoldenBicycleCompany.ApplicationServices
{
    public class CustomerManagementService : ICustomerManagementService
    {
        public CustomerManagementService(ICustomerRepository customerRepository) {
            Check.Require(customerRepository != null, "customerRepository may not be null");

            this.customerRepository = customerRepository;
        }

        public Customer Get(int id) {
            return customerRepository.Get(id);
        }

        public IList<Customer> GetAll() {
            return customerRepository.GetAll();
        }

        public IList<CustomerDto> GetCustomerSummaries() {
            return customerRepository.GetCustomerSummaries();
        }

        public CustomerFormViewModel CreateFormViewModel() {
            CustomerFormViewModel viewModel = new CustomerFormViewModel();
            return viewModel;
        }

        public CustomerFormViewModel CreateFormViewModelFor(int customerId) {
            Customer customer = customerRepository.Get(customerId);
            return CreateFormViewModelFor(customer);
        }

        public CustomerFormViewModel CreateFormViewModelFor(Customer customer) {
            CustomerFormViewModel viewModel = CreateFormViewModel();
            viewModel.Customer = customer;
            return viewModel;
        }

        public ActionConfirmation SaveOrUpdate(Customer customer) {
            if (customer.IsValid()) {
                customerRepository.SaveOrUpdate(customer);

                ActionConfirmation saveOrUpdateConfirmation = ActionConfirmation.CreateSuccessConfirmation(
                    "The customer was successfully saved.");
                saveOrUpdateConfirmation.Value = customer;

                return saveOrUpdateConfirmation;
            }
            else {
                customerRepository.DbContext.RollbackTransaction();

                return ActionConfirmation.CreateFailureConfirmation(
                    "The customer could not be saved due to missing or invalid information.");
            }
        }

        public ActionConfirmation UpdateWith(Customer customerFromForm, int idOfCustomerToUpdate) {
            Customer customerToUpdate = 
                customerRepository.Get(idOfCustomerToUpdate);
            TransferFormValuesTo(customerToUpdate, customerFromForm);

            if (customerToUpdate.IsValid()) {
                ActionConfirmation updateConfirmation = ActionConfirmation.CreateSuccessConfirmation(
                    "The customer was successfully updated.");
                updateConfirmation.Value = customerToUpdate;

                return updateConfirmation;
            }
            else {
                customerRepository.DbContext.RollbackTransaction();

                return ActionConfirmation.CreateFailureConfirmation(
                    "The customer could not be saved due to missing or invalid information.");
            }
        }

        public ActionConfirmation Delete(int id) {
            Customer customerToDelete = customerRepository.Get(id);

            if (customerToDelete != null) {
                customerRepository.Delete(customerToDelete);

                try {
                    customerRepository.DbContext.CommitChanges();
                    
                    return ActionConfirmation.CreateSuccessConfirmation(
                        "The customer was successfully deleted.");
                }
                catch {
                    customerRepository.DbContext.RollbackTransaction();

                    return ActionConfirmation.CreateFailureConfirmation(
                        "A problem was encountered preventing the customer from being deleted. " +
                        "Another item likely depends on this customer.");
                }
            }
            else {
                return ActionConfirmation.CreateFailureConfirmation(
                    "The customer could not be found for deletion. It may already have been deleted.");
            }
        }

        private void TransferFormValuesTo(Customer customerToUpdate, Customer customerFromForm) {
		    customerToUpdate.ValidLicenseNumber = customerFromForm.ValidLicenseNumber;
			customerToUpdate.FirstName = customerFromForm.FirstName;
			customerToUpdate.MiddleName = customerFromForm.MiddleName;
			customerToUpdate.LastName = customerFromForm.LastName;
			customerToUpdate.BirthDate = customerFromForm.BirthDate;
        }

        ICustomerRepository customerRepository;
    }
}
